﻿using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Transport.Channels;
using PSAMMatrixCloud.Common;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace PSAMMatrixCloud.TransferSecret.LaneMutual
{
    public class MessageDecoder : ByteToMessageDecoder
    {
        private static short ProtocolHead = 0x55AA;
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
        {
            var TouchTime = DateTime.Now;

            //内存回收
            GC.Collect();
            if (input.ReadableBytes <= Message.ProtocolPackageMinLength) {
                return;
            }
            
            while (true)
            {
                // 记录下索引，后面会用到
                int bufferIndex = input.ReaderIndex;
                input.MarkReaderIndex();
                
                //检查是否读到包头
                if (input.ReadShort() == ProtocolHead)
                {
                    //读一个字节帧序号
                    byte RSCTL = input.ReadByte();
                    //数据长度
                    short length = input.ReadShort();

                    length = (short)(GetHighWord(length) + GetLowWord(length));
                    // 包数据齐不齐
                    if (input.ReadableBytes < length)
                    {
                        //重置一下标记
                        input.SetReaderIndex(bufferIndex);
                        return;
                    }
                    input.SetReaderIndex(bufferIndex);
                    //内存回收
                    GC.Collect();
                    var data = new byte[length + 7];
                    input.ReadBytes(data);

                    try
                    {
                        Message DataPackage = new Message(data);
                        LogHelper.Info("解码触发时间："+ TouchTime.ToString("yyyy-MM-dd HH:mm:ss fff") + "   车道向云端发起请求数据帧：" + Check.ByteArrayToHexString(data));
                        LogHelper.Debug("数据缓冲区长度：" + output.Count);
                        output.Add(DataPackage);
                        data = null;
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Error($"解析数据包出错:{Check.ByteArrayToHexString(data)}", ex);
                        throw;
                    }
                    //内存回收
                    GC.Collect();
                    if (input.ReadableBytes <= Message.ProtocolPackageMinLength)
                    {
                        return;
                    }
                    continue;
                }
                else
                {
                    // 读不到包头的话还原一下标记，然后丢掉一个字节
                    input.ResetReaderIndex();
                }
                input.ReadByte();
                if (input.ReadableBytes <= Message.ProtocolPackageMinLength)
                {
                    return;
                }
            }

            
        }


        public short GetHighWord(short intval)
        {
            return (short)(intval >> 8);
        }

        public short GetLowWord(short intval)
        {
            return (short)(intval<<8);
        }
    }
}